package controller

import (
	"ahutoj/web/io/constanct"
	"ahutoj/web/io/request"
	"ahutoj/web/io/response"
	"ahutoj/web/logic"
	"ahutoj/web/utils"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

// @Summary	获取对象
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		GetObjectReq	body		request.GetObjectReq	true	"-"
// @Success	200				{object}	response.GetObjectResp
// @Success	201				{object}	response.GetPresignedObjectResp
// @Router		/api/oss/object/get/ [post]
func GetObject(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.GetObjectReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.GetObject(ctx, req)
	if err != nil {
		logger.Errorf("call GetObject failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	上传对象
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		PutObjectReq	body		request.PutObjectReq	true	"-"
// @Param		file			formData	file					true	"file"
// @Success	200				{object}	response.UploadInfo
// @Router		/api/oss/object/put/ [post]
func PutObject(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.PutObjectReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.FormMultipart); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.PutObject(ctx, req)
	if err != nil {
		logger.Errorf("call GPutObjectfailed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取桶下对象列表
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		Prefix	query		string	true	"-"
// @Param		bucket	path		string	true	"-"
// @Success	200		{object}	[]response.ObjectInfo
// @Router		/api/oss/object/:bucket [get]
func GetObjects(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.GetObjectsReq)
	req.BucketName = ctx.Param("bucket")
	req.Prefix = ctx.Query("Prefix")
	resp, err := logic.GetObjects(ctx, req)
	if err != nil {
		logger.Errorf("call GetObjects failed,req=%+v,err=%s", req.BucketName, err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	本地下载
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		FGetObjectReq	body	request.FGetObjectReq	true	"-"
// @Success	200				{object}	response.Response
// @Router		/api/oss/object/getfile/ [post]
func FGetObject(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.FGetObjectReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.FGetObject(ctx, req)
	if err != nil {
		logger.Errorf("call FGetObject failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary		本地上传
// @Description	好像没什么用= =
// @Tags			Oss
// @Accept			json
// @Produce		json
// @Param			FPutObjectReq	body		request.FPutObjectReq	true	"-"
// @Success		200				{object}	response.UploadInfo
// @Router			/api/oss/object/putfile/ [post]
func FPutObject(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.FPutObjectReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.FPutObject(ctx, req)
	if err != nil {
		logger.Errorf("call FPutObject failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}
// @Summary		桶内改名，跨桶复制
// @Description	
// @Tags			Oss
// @Accept			json
// @Produce		json
// @Param			ModifyObjectReq	body		request.ModifyObjectReq	true	"-"
// @Success		200				{object}	response.UploadInfo
// @Router			/api/oss/object/modify/ [post]
func ModifyObject(ctx *gin.Context){
	logger := utils.GetLogInstance()
	req := new(request.ModifyObjectReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.ModifyObject(ctx, req)
	if err != nil {
		logger.Errorf("call RenameObject failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

//func CreateObject(ctx *gin.Context) {
//	logger := utils.GetLogInstance()
//	req := new(request.CreateObjectReq)
//	var err error
//	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
//		// 请求参数有误，直接返回响应
//		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
//		response.ResponseError(ctx, constanct.InvalidParamCode)
//		return
//	}
//	resp, err := logic.CreateObject(ctx, req)
//	if err != nil {
//		logger.Errorf("call CreateObject failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
//		response.ResponseError(ctx, constanct.ServerErrorCode)
//	}
//	response.ResponseOK(ctx, resp)
//}


// @Summary	删除对象
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		DeleteObjectReq	body		request.DeleteObjectReq	true	"-"
// @Success	200				{object}	response.Response
// @Router		/api/oss [post]
func DeleteObject(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.DeleteObjectReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.DeleteObject(ctx, req)
	if err != nil {
		logger.Errorf("call DeleteObject failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取对象信息
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		GetObjectInfoReq	body		request.GetObjectInfoReq	true	"-"
// @Success	200					{object}	response.UploadInfo
// @Router		/api/oss/object/info/ [post]
// @typedef	response.GetObjectInfoResp
func GetObjectInfo(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.GetObjectInfoReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.GetObjectInfo(ctx, req)
	if err != nil {
		logger.Errorf("call GetObjectInfo failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取桶列表
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Success	200	{object}	[]response.BucketInfo
// @Router		/api/oss/bucket [get]
func GetBuckets(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	var err error
	resp, err := logic.GetBucket(ctx)
	if err != nil {
		logger.Errorf("call GetBucket failed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取桶状态，true存在，false不存在
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		bucket	path		string	true	"-"
// @Success	200				{object}	response.GetBucketStatsResp
// @Router		/api/oss/bucket/{bucket}/stats/ [get]
func GetBucketStats(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.GetBucketStatsReq)
	req.BucketName = ctx.Param("bucket")
	resp, err := logic.GetBucketStats(ctx,req)
	if err != nil {
		logger.Errorf("call GetBucketStats failed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取桶策略
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		bucket	path		string	true	"-"
// @Success	200				{object}	response.GetBucketPolicyResp
// @Router		/api/oss/bucket/{bucket}/policy/ [get]
func GetBucketPolicy(ctx *gin.Context){
	logger := utils.GetLogInstance()
	req := new(request.GetBucketPolicyReq)
	req.BucketName = ctx.Param("bucket")
	resp, err := logic.GetBucketPolicy(ctx,req)
	if err != nil {
		logger.Errorf("call GetBucketPolicy failed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}
// @Summary	设置桶策略
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		bucket	path		string	true	"-"
// @Param		SetBucketPolicyReq	body		request.SetBucketPolicyReq	true	"-"
// @Success	200				{object}	response.Response
// @Router		/api/oss/bucket/{bucket}/policy/ [post]
func SetBucketPolicy(ctx *gin.Context){
	logger := utils.GetLogInstance()
	req := new(request.SetBucketPolicyReq)
	var err error
	req.BucketName = ctx.Param("bucket")
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.SetBucketPolicy(ctx,req)
	if err != nil {
		logger.Errorf("call GetBucketPolicy failed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}
// @Summary	创建桶
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		CreateBucketReq	body		request.CreateBucketReq	true	"-"
// @Success	200				{object}	response.Response
// @Router		/api/oss/bucket/add/ [post]
func CreateBucket(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.CreateBucketReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}

	resp, err := logic.CreateBucket(ctx, req)
	if err != nil {
		logger.Errorf("call CreateBucket failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	移除桶
// @Description
// @Tags		Oss
// @Accept		json
// @Produce	json
// @Param		RemoveBucketReq	body		request.RemoveBucketReq	true	"-"
// @Success	200				{object}	response.Response
// @Router		/api/oss/bucket/delete/ [post]
func RemoveBucket(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.RemoveBucketReq)
	var err error
	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
		// 请求参数有误，直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.RemoveBucket(ctx, req)
	if err != nil {
		logger.Errorf("call RemoveBucket failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

//func UnzipObject(ctx *gin.Context) {
//	logger := utils.GetLogInstance()
//	req := new(request.UnzipReq)
//	var err error
//	if err = ctx.ShouldBindWith(req, binding.JSON); err != nil {
//		// 请求参数有误，直接返回响应
//		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
//		response.ResponseError(ctx, constanct.InvalidParamCode)
//		return
//	}
//	resp, err := logic.UnzipObject(ctx, req)
//	if err != nil {
//		logger.Errorf("call UnzipObject failed,req=%+v,err=%s", utils.Sdump(req), err.Error())
//		response.ResponseError(ctx, constanct.ServerErrorCode)
//		return
//	}
//	response.ResponseOK(ctx, resp)
//}
